﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using Fiddler;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.IO.Compression;
using System.Timers;
using Microsoft.VisualBasic;

namespace WebSniffer
{
    //http://www.englisch-hilfen.de/en/games/hangman26.html
    public partial class Form1 : Form
    {
        Random rnd = new Random();
        #region Variable type Int
        int gamesPlayed = 0;
        int totalGamesPlayed = 1;//changed this back to 0 after testing
        static int iSecureEndpointPort = 7777;
        int index, GameWin, GameLoss, length , TotalWin, TotalLoss = 0;
        private const UInt32 MouseEventLeftDown = 0x0002;
        private const UInt32 MouseEventLeftUp = 0x0004;
        int gameLimit = 10;
        #endregion
        #region Variable type Short
        short numMistakes = 6;
        #endregion
        #region Variable type Strings
        string currentResponse = "";
        String prevWord = "";
        String GameWord = "";
        String currentword = "";
        static string sSecureEndpointHostname = "localhost";
        #endregion
        #region Variable type Bool
        bool gameEnd = false;
        bool CurrentlyBusy = false;
        bool firstTry = true;
        [DllImport("user32.dll")]
        public static extern bool SetCursorPos(int x, int y);
        #endregion
        #region Variable type Lists
        List<String> gameWordList = new List<string>();
        List<String> prevGameWordList = new List<string>();
        List<Char> letterList = new List<char>();
        List<Char> vowelList = new List<char>();
        List<Char> RandomList = new List<char>();
        #endregion
        #region Variable type Other Variables
        static Proxy oSecureEndpoint;
        [DllImport("user32.dll")]
        private static extern void mouse_event(UInt32 dwFlags, UInt32 dx, UInt32 dy, UInt32 dwData, IntPtr dwExtraInfo);
        char[] alphabet = Enumerable.Range('A', 26).Select(x => (char)x).ToArray();//Fill the list with all letters
        char letter;
        char choice = ' ';
        System.Timers.Timer time = new System.Timers.Timer(4250);//changed for testing from 3250
        static Dictionary<string, ClickPoint> clickPoints = new Dictionary<string, ClickPoint>();
        Dictionary<string, int> wordDict = new Dictionary<string, int>();
        Dictionary<char, int> letterDict = new Dictionary<char, int>();
        #endregion
        #region Regular Expressions
        Regex regGameOv = new Regex(@"{.solved.:.*}");
        Regex regRightResponse = new Regex(@"{.*.tries.:[0-9]}");
        Regex regFinalWordLoss = new Regex(@".solution.:.*word");
        Regex regFinalWordWin = new Regex(@"{.*solved.*true.*}");
        Regex regSolvedTrue = new Regex(@"{.solved.:.*,.err");
        Regex regcurrentWord = new Regex(@".word.:..*.,.letters");
        Regex regPhraseLength = new Regex(@"_");//not needed
        #endregion

        public Form1()
        {
            InitializeComponent();
        }
        struct ClickPoint
        {
            public int X;
            public int Y;
        }

        public void AddToDictionary()
        {
            //All points were found in firefox, maximized window
            clickPoints.Add("Letter A", new ClickPoint() { X = 205, Y = 608 });
            clickPoints.Add("Letter B", new ClickPoint() { X = 229, Y = 610 });
            clickPoints.Add("Letter C", new ClickPoint() { X = 255, Y = 611 });
            clickPoints.Add("Letter D", new ClickPoint() { X = 276, Y = 611 });
            clickPoints.Add("Letter E", new ClickPoint() { X = 302, Y = 610 });
            clickPoints.Add("Letter F", new ClickPoint() { X = 324, Y = 608 });
            clickPoints.Add("Letter G", new ClickPoint() { X = 351, Y = 608 });
            clickPoints.Add("Letter H", new ClickPoint() { X = 373, Y = 609 });
            clickPoints.Add("Letter I", new ClickPoint() { X = 398, Y = 610 });
            clickPoints.Add("Letter J", new ClickPoint() { X = 420, Y = 609 });
            clickPoints.Add("Letter K", new ClickPoint() { X = 444, Y = 607 });
            clickPoints.Add("Letter L", new ClickPoint() { X = 466, Y = 607 });
            clickPoints.Add("Letter M", new ClickPoint() { X = 493, Y = 608 });
            clickPoints.Add("Letter N", new ClickPoint() { X = 206, Y = 633 });
            clickPoints.Add("Letter O", new ClickPoint() { X = 230, Y = 632 });
            clickPoints.Add("Letter P", new ClickPoint() { X = 254, Y = 631 });
            clickPoints.Add("Letter Q", new ClickPoint() { X = 278, Y = 632 });
            clickPoints.Add("Letter R", new ClickPoint() { X = 301, Y = 631 });
            clickPoints.Add("Letter S", new ClickPoint() { X = 326, Y = 631 });
            clickPoints.Add("Letter T", new ClickPoint() { X = 350, Y = 632 });
            clickPoints.Add("Letter U", new ClickPoint() { X = 375, Y = 632 });
            clickPoints.Add("Letter V", new ClickPoint() { X = 400, Y = 631 });
            clickPoints.Add("Letter W", new ClickPoint() { X = 423, Y = 631 });
            clickPoints.Add("Letter X", new ClickPoint() { X = 445, Y = 630 });
            clickPoints.Add("Letter Y", new ClickPoint() { X = 471, Y = 632 });
            clickPoints.Add("Letter Z", new ClickPoint() { X = 493, Y = 632 });
            clickPoints.Add("New Game Button(After Win or Loss)", new ClickPoint() { X = 227, Y = 634 });
        }

        public void ProcessResponse(string resp)
        {
            //Solution key word only appears in the response if the game was lost
            if ((regFinalWordLoss.IsMatch(resp) == false) && (regFinalWordWin.IsMatch(resp) == false) && (regRightResponse.IsMatch(resp)) && (CurrentlyBusy == false))//if solution isnt present IE game not over Or if solved is true
            {
                CurrentlyBusy = true;
                currentResponse = resp;
                Regex regLettersGuessedThisGame = new Regex(@".letters.:\[.[a-z]..*\]");
                log("Method:ProcessResponse (Beginning)", 132);
                length = wordLength(currentResponse);
                currentword = regcurrentWord.Match(currentResponse).ToString().Replace("word", "").Replace(":", "").Replace(",", "").Replace("\"", "").Replace("\\", "").Replace("_", "").Replace("letters", "").Replace("[", "");
                List<string> possibles = new List<string>();
                //String is empty so guess as smart as possible
                //thinking works best if theres atleast one letter in it
                if (!String.IsNullOrEmpty(currentword))
                {
                    //Smartest way of picking a letter
                    choice = Thinking(length, ref possibles);
                }
                else
                {
                    //call smartchoice for a choice
                    choice = SmartChoice(length);
                }
                log("Method:ProcessResponse (After choice was returned)", 148);
                #region Check For Mistakes
                log("Method:ProcessResponse (Checking for Mistake)", 150);
                if (currentword.Equals(prevWord))//letter guessed was wrong
                {
                    numMistakes--;//only get 6 mistakes per game
                }
                prevWord = currentword;
                lblGuessesLeft.Invoke((Action)(() => { lblGuessesLeft.Text = "Guesses Left: " + numMistakes; }));
                #endregion
                #region Obtaining Letters Used
                log("Method:ProcessResponse (Getting Letters Used)", 159);
                if (regLettersGuessedThisGame.IsMatch(currentResponse))
                {
                    MatchCollection lettersUsed = regLettersGuessedThisGame.Matches(currentResponse);
                    String cleanedLettersGuessed = "";
                    lbLetters.Invoke((Action)(() => { lbLetters.Items.Clear(); }));
                    foreach (var match in lettersUsed)
                    {
                        cleanedLettersGuessed = match.ToString().Replace("[", "").Replace("]", "").Replace(",", "").Replace('"', ' ').Replace("letters", "").Replace(":", "");
                        cleanedLettersGuessed = cleanedLettersGuessed.Trim().Replace(" ", "");
                        lbLetters.Invoke((Action)(() => { lbLetters.Items.Add(cleanedLettersGuessed); }));
                    }
                }
                #endregion
                if (gamesPlayed == 0)
                {
                    lblDidIWinOrLose.Invoke((Action)(() => { lblDidIWinOrLose.Text = "Did I Win Or Lose Last Game ? : " + "\n" + "First Game Not Done Yet!"; }));
                }
                lbPossibles.Invoke((Action)(() => { lbPossibles.DataSource = null; }));
                lbPossibles.Invoke((Action)(() => { lbPossibles.DataSource = possibles; }));
                //possibles.Clear();
                Thread.Sleep(1350);
                log("Method:ProcessResponse (About to send click)", 181);
                #region Letter Selection
                if (choice.Equals('*'))//thinking couldn't find a good choice,Randomize one from the most common used letters
                {
                    log("Method:ProcessResponse (Doing a random letter selection)", 185);
                  //just in case the file cant be found that populates the lists
                    if (RandomList.Count > 0)
                    {

                        index = rnd.Next(0, RandomList.Count); // Pick one at random
                        letter = RandomList[index];
                        if ((letterList.Contains(letter)) && (RandomList.Contains(letter)))
                        {
                            RandomList.RemoveAt(index);//takes the picked letter out of the list
                            index = letterList.IndexOf(letter);
                            letterList.RemoveAt(index);//THIS Isnt working, wont delete the letter sometimes
                        }
                        /*else//should be fixed //infinite loop needs to be an uppercase letter and also fix how its added to the randomlist
                        {//PROBLEM IS IN HERE!!!!!!!
                            log("Method:ProcessResponse (Doing a random letter selection inside the Else)", 197);
                            letter = Char.ToUpper(letter);
                            while (!letterList.Contains(letter))
                            {
                                if (RandomList.Count > 0)
                                {
                                    index = rnd.Next(0, RandomList.Count); // Pick one at random
                                    letter = RandomList[index];
                                }
                                else
                                {
                                    index = rnd.Next(0, letterList.Count); // Pick one at random
                                    letter = letterList[index];
                                    letterList.RemoveAt(index);
                                }
                            }
                            RandomList.RemoveAt(index);//takes the picked letter out of the list
                            letterList.RemoveAt(letterList.IndexOf(letter));//toUpper the letter
                        *///}//never makes it to this line infite loop above
                        log("Method:ProcessResponse (Leaving random letter selection)", 219);
                    }
                    else
                    {
                        index = rnd.Next(0, letterList.Count); // Pick one at random
                        letter = letterList[index];
                        letterList.RemoveAt(index);
                        log("Method:ProcessResponse (Doing a random letter selection inside the Else)", 226);
                    }
                    log("Method:ProcessResponse (Entering click send(random way))", 228);
                    switch (letter)
                    {
                        case 'A':
                            SendClick(clickPoints["Letter A"]);
                            break;
                        case 'B':
                            SendClick(clickPoints["Letter B"]);
                            break;
                        case 'C':
                            SendClick(clickPoints["Letter C"]);
                            break;
                        case 'D':
                            SendClick(clickPoints["Letter D"]);
                            break;
                        case 'E':
                            SendClick(clickPoints["Letter E"]);
                            break;
                        case 'F':
                            SendClick(clickPoints["Letter F"]);
                            break;
                        case 'G':
                            SendClick(clickPoints["Letter G"]);
                            break;
                        case 'H':
                            SendClick(clickPoints["Letter H"]);
                            break;
                        case 'I':
                            SendClick(clickPoints["Letter I"]);
                            break;
                        case 'J':
                            SendClick(clickPoints["Letter J"]);
                            break;
                        case 'K':
                            SendClick(clickPoints["Letter K"]);
                            break;
                        case 'L':
                            SendClick(clickPoints["Letter L"]);
                            break;
                        case 'M':
                            SendClick(clickPoints["Letter M"]);
                            break;
                        case 'N':
                            SendClick(clickPoints["Letter N"]);
                            break;
                        case 'O':
                            SendClick(clickPoints["Letter O"]);
                            break;
                        case 'P':
                            SendClick(clickPoints["Letter P"]);
                            break;
                        case 'Q':
                            SendClick(clickPoints["Letter Q"]);
                            break;
                        case 'R':
                            SendClick(clickPoints["Letter R"]);
                            break;
                        case 'S':
                            SendClick(clickPoints["Letter S"]);
                            break;
                        case 'T':
                            SendClick(clickPoints["Letter T"]);
                            break;
                        case 'U':
                            SendClick(clickPoints["Letter U"]);
                            break;
                        case 'V':
                            SendClick(clickPoints["Letter V"]);
                            break;
                        case 'W':
                            SendClick(clickPoints["Letter W"]);
                            break;
                        case 'X':
                            SendClick(clickPoints["Letter X"]);
                            break;
                        case 'Y':
                            SendClick(clickPoints["Letter Y"]);
                            break;
                        case 'Z':
                            SendClick(clickPoints["Letter Z"]);
                            break;
                    }
                    log("Method:ProcessResponse (Leaving click send (random way))", 310);
                    letter = ' ';
                    choice = ' ';
                }
                else if(!choice.Equals('*'))//this is where the thinking choice goes or the Smart choice goes
                {
                    log("Method:ProcessResponse (Entering click send (smart way))", 316);
                    index = letterList.IndexOf(choice);
                    letter = letterList[index];
                    letterList.RemoveAt(index);//takes the picked letter out of the list
                    switch (letter)
                    {
                        case 'A':
                            SendClick(clickPoints["Letter A"]);
                            break;
                        case 'B':
                            SendClick(clickPoints["Letter B"]);
                            break;
                        case 'C':
                            SendClick(clickPoints["Letter C"]);
                            break;
                        case 'D':
                            SendClick(clickPoints["Letter D"]);
                            break;
                        case 'E':
                            SendClick(clickPoints["Letter E"]);
                            break;
                        case 'F':
                            SendClick(clickPoints["Letter F"]);
                            break;
                        case 'G':
                            SendClick(clickPoints["Letter G"]);
                            break;
                        case 'H':
                            SendClick(clickPoints["Letter H"]);
                            break;
                        case 'I':
                            SendClick(clickPoints["Letter I"]);
                            break;
                        case 'J':
                            SendClick(clickPoints["Letter J"]);
                            break;
                        case 'K':
                            SendClick(clickPoints["Letter K"]);
                            break;
                        case 'L':
                            SendClick(clickPoints["Letter L"]);
                            break;
                        case 'M':
                            SendClick(clickPoints["Letter M"]);
                            break;
                        case 'N':
                            SendClick(clickPoints["Letter N"]);
                            break;
                        case 'O':
                            SendClick(clickPoints["Letter O"]);
                            break;
                        case 'P':
                            SendClick(clickPoints["Letter P"]);
                            break;
                        case 'Q':
                            SendClick(clickPoints["Letter Q"]);
                            break;
                        case 'R':
                            SendClick(clickPoints["Letter R"]);
                            break;
                        case 'S':
                            SendClick(clickPoints["Letter S"]);
                            break;
                        case 'T':
                            SendClick(clickPoints["Letter T"]);
                            break;
                        case 'U':
                            SendClick(clickPoints["Letter U"]);
                            break;
                        case 'V':
                            SendClick(clickPoints["Letter V"]);
                            break;
                        case 'W':
                            SendClick(clickPoints["Letter W"]);
                            break;
                        case 'X':
                            SendClick(clickPoints["Letter X"]);
                            break;
                        case 'Y':
                            SendClick(clickPoints["Letter Y"]);
                            break;
                        case 'Z':
                            SendClick(clickPoints["Letter Z"]);
                            break;
                    }
                    log("Method:ProcessResponse (Leaving click send (smart way))", 401);
                }
                CurrentlyBusy = false;
                currentResponse = " ";
                choice = ' ';
                letter = ' ';
                #endregion
            }
            #region Checking if the game is over
            else if ((regRightResponse.IsMatch(resp)) && (!CurrentlyBusy))
            {
                log("Method:ProcessResponse (Entering game over check)", 412);
                /*if the program solves the word on its own then the solution key word doesn't appear, 
                 * but if the program doesn't solve it correctly then solution key word does appear in the resp*/
                CurrentlyBusy = true;
                currentResponse = resp;
                if ((regFinalWordWin.IsMatch(currentResponse)))
                {//won the game
                    log("Method:ProcessResponse (Entering game won)", 419);
                    gameEnd = true;
                    firstTry = true;
                    totalGamesPlayed = 0;
                    TotalWin = 0;
                    TotalLoss = 0;
                    lblDidIWinOrLose.Invoke((Action)(() => { lblDidIWinOrLose.Text = "Did I Win Or Lose Last Game ? : " + "Won"; }));
                    //Gets The word that was being guessed and adds it to a listbox
                    Regex regWord = new Regex(@".word.:.*,.lett");
                    GameWord = regWord.Match(currentResponse).ToString().Replace("word", "").Replace(":", "").Replace(",", "").Replace("lett", "").Replace("\"", "").Replace("\\", "");
                    writeGameWord(GameWord);
                    gameWordList.Add(GameWord + " Won");
                    lbWordCollection.Invoke((Action)(() => { lbWordCollection.DataSource = null; }));
                    lbWordCollection.Invoke((Action)(() => { lbWordCollection.DataSource = gameWordList; }));
                    if (gameEnd)
                    {
                        lbLetters.Invoke((Action)(() => { lbLetters.Items.Clear(); }));
                        prevWord = "";
                        currentword = "";
                        currentResponse = "";
                        letterList.Clear();
                        letterList.AddRange(alphabet);//add all the letters back
                        numMistakes = 6;
                        lblGuessesLeft.Invoke((Action)(() => { lblGuessesLeft.Text = "Guesses Left: " + numMistakes; }));
                        gamesPlayed++;
                        GameWin++;
                        lblGameRatio.Invoke((Action)(() => { lblGameRatio.Text = " Win Loss Ratio: " + GameWin + " : " + GameLoss; }));
                        lblGamesPlayed.Invoke((Action)(() => { lblGamesPlayed.Text = "Games Played: " + gamesPlayed.ToString(); }));
                        prevGameWordList.Clear();
                        wordsPrevUsed();
                        if ((gamesPlayed != gameLimit))
                        {
                            SendClick(clickPoints["New Game Button(After Win or Loss)"]);
                            time.Enabled = true;
                        }
                    }
                    log("Method:ProcessResponse (leavingg game won)", 455);
                }
                else if ((regFinalWordLoss.IsMatch(currentResponse)))
                {
                    log("Method:ProcessResponse (Entering game lost)", 459);
                    gameEnd = true;
                    firstTry = true;
                    totalGamesPlayed = 0;
                    lblDidIWinOrLose.Invoke((Action)(() => { lblDidIWinOrLose.Text = "Did I Win Or Lose Last Game ? : " + "Lost"; }));
                    GameWord = regFinalWordLoss.Match(currentResponse).ToString().Replace("word", "").Replace(":", "").Replace(",", "").Replace("solution", "").Replace("\"", "");
                    writeGameWord(GameWord);
                    gameWordList.Add(GameWord + " Lost");
                    lbWordCollection.Invoke((Action)(() => { lbWordCollection.DataSource = null; }));
                    lbWordCollection.Invoke((Action)(() => { lbWordCollection.DataSource = gameWordList; }));
                    lblGamesPlayed.Invoke((Action)(() => { lblGamesPlayed.Text = "Games Played: " + gamesPlayed.ToString(); }));
                    lbLetters.Invoke((Action)(() => { lbLetters.Items.Clear(); }));
                    prevWord = "";
                    currentword = "";
                    currentResponse = "";
                    numMistakes = 6;
                    lblGuessesLeft.Invoke((Action)(() => { lblGuessesLeft.Text = "Guesses Left: " + numMistakes; }));
                    gamesPlayed++;
                    GameLoss++;
                    lblGameRatio.Invoke((Action)(() => { lblGameRatio.Text = " Win Loss Ratio: " + GameWin + " : " + GameLoss; }));
                    lblGamesPlayed.Invoke((Action)(() => { lblGamesPlayed.Text = "Games Played: " + gamesPlayed.ToString(); }));
                    letterList.Clear();
                    letterList.AddRange(alphabet);//add all the letters back
                    prevGameWordList.Clear();
                    wordsPrevUsed();
                    if ((gamesPlayed != gameLimit))
                    {
                        SendClick(clickPoints["New Game Button(After Win or Loss)"]);
                        time.Enabled = true;
                    }
                    log("Method:ProcessResponse (Leaving game lost)", 489);
                }
                if (gamesPlayed == gameLimit)
                {
                    log("Method:ProcessResponse (Entering game cycle end)", 493);
                    FiddlerApplication.BeforeResponse -= FiddlerApplication_BeforeResponse;
                    FiddlerApplication.oProxy.Detach();
                    Thread.Sleep(100);
                    FiddlerApplication.Shutdown();
                    btnStop.Invoke((Action)(() => { btnStop.Enabled = false; }));
                    btnStart.Invoke((Action)(() => { btnStart.Enabled = true; }));
                    lblIsRunning.Invoke((Action)(() => { lblIsRunning.Text = "Program Stopped"; }));
                    lblStopped.Invoke((Action)(() => { lblStopped.Visible = true; }));
                    lblRunning.Invoke((Action)(() => { lblRunning.Visible = false; }));
                    lbLetters.Invoke((Action)(() => { lbLetters.Items.Clear(); }));
                    //write game words that came up and the # of games that are played so far
                    gameWordList.Sort();
                    log("Method:ProcessResponse (writing game words to file)", 506);
                    writeGameData();
                    numMistakes = 6;
                    letterList.Clear();
                    lbWordCollection.Invoke((Action)(() => { lbWordCollection.DataSource = null; }));
                    lbWordCollection.Invoke((Action)(() => { lbWordCollection.DataSource = gameWordList; }));
                    firstTry = true;
                    totalGamesPlayed = 0;
                    prevGameWordList.Clear();
                    wordsPrevUsed();
                    //Re enable the start button
                    CurrentlyBusy = false;
                    MessageBox.Show("Game Limit of " + gameLimit +" has been reached game now stopping!", "Game Limit", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    log("Method:ProcessResponse (Leaving game cycle end)", 519);
                    log("Game Cycle is over!!!!!", 520);
                }
            }
            #endregion
        }
        /// <summary>
        /// Writes the current game word to a file.
        /// </summary>
        /// <param name="word2"></param>
        private void writeGameWord(string word2)
        {
            log("Method:writeGameWord (Entering method)", 531);
            using (TextWriter writer = new StreamWriter("C:\\Users\\tgabelhart\\Documents\\WordList.txt", true))
            {
                word2 = word2.Replace(" Won", "").Replace(" Lost", "").TrimEnd(' ');
                writer.WriteLine(word2);
            }
            log("Method:writeGameWord (Leaving method)", 537);
        }
        /// <summary>
        /// Writes the game data to a file. IE how many games were won,lost, and played
        /// </summary>
        private void writeGameData()
        {
            log("Method:writeGameData (Entering method)", 544);
            using (TextWriter writer = new StreamWriter("C:\\Users\\tgabelhart\\Documents\\WordList.txt", true))
            {
                writer.WriteLine("Games Played: " + gamesPlayed + " Games Won:" + GameWin + " Games Lost: " + GameLoss);
            }
            log("Method:writeGameData (Leaving method)", 549);
        }

        public static void SendMouseClick()
        {
            mouse_event(MouseEventLeftDown, 0, 0, 0, new IntPtr());
            mouse_event(MouseEventLeftUp, 0, 0, 0, new IntPtr());
        }
        
        private static void SendClick(ClickPoint cp)
        {
            SetCursorPos(cp.X, cp.Y);
            SendMouseClick();
        }

        /// <summary>
        /// Returns the length of the current word.
        /// </summary>
        /// <param name="recivedResponse"></param>
        /// <returns></returns>
        public int wordLength(string recivedResponse)
        {//can be elimanted and just used in the main method
            log("Method:wordLength (Entering wordLength)", 571);
            int matchCount = 0;
            String underscoreColl = regcurrentWord.Match(currentResponse).ToString().Replace("word", "").Replace(":", "").Replace(",", "").Replace("\"", "").Replace("\\", "").Replace("letters", "").Replace("[", "");
            matchCount = underscoreColl.Length;
            lblCurrentWordLength.Invoke((Action)(() => { lblCurrentWordLength.Text = "Current word length is: " + matchCount; }));
            log("Method:wordLength (Leaving wordLength)", 576);
            return matchCount;
        }

        /// <summary>
        /// Smartest way to pick a letter breaks down into a list of possibles by length and returns a letter to pick
        /// </summary>
        /// <param name="currentPhraseLength"></param>
        /// <param name="possibles"></param>
        /// <returns></returns>
        public char Thinking(int currentPhraseLength, ref List<string> possibles)
        {
            log("Method:Thinking (Entering Thinking)", 588);
            string possibleString = "";
            foreach (var item in prevGameWordList)
            {
                int listWordLength = item.Length;
                if (currentPhraseLength == listWordLength)
                {
                    if (!possibles.Contains(item))
                    {//item isn't already in possibles, so add it
                        possibles.Add(item);
                    }
                }
            }
            log("Method:Thinking (Leaving possible list populating)", 601);
            //Put all words into a string so I can search using a regular expression
            log("Method:Thinking (Entering possible string appending)", 603);
            foreach (var usedWord in possibles)
            {
                possibleString += usedWord + "\n";
            }
            log("Method:Thinking (Leaving possible string appending)", 608);
            //Now shorten the possible list down to the closest possibles
            string word = regcurrentWord.Match(currentResponse).ToString().Replace("word", "").Replace(":", "").Replace(",", "").Replace("\"", "").Replace("\\", "").Replace("_", ".").Replace("letters", "").Replace("[", "");
            Regex listSlimmer = new Regex(word);
            MatchCollection closestPossibles = listSlimmer.Matches(possibleString);
            //Clear the list for the new closest possibles
            possibles.Clear();
            //Add the new possibles into the list
            log("Method:Thinking (Entering possible list populating 2)", 616);
            foreach (var match in closestPossibles)
            {
                possibles.Add(match.ToString().ToUpper());
            }
            log("Method:Thinking (Leaving possible list populating 2)", 621);
            //Now that the list of possibles is built find a letter that is unique and pick it
            log("Method:Thinking (Entering unique letter selection)", 623);
            foreach (string possible in possibles)
            {
                foreach (char letter in possible.ToCharArray())
                {
                    int hits = 0;
                    foreach (var possibleChoice in possibles)
                    {
                        if (possibleChoice.Contains(letter))
                        {
                            hits++;
                            if (hits > 1)
                            {
                                break;
                            }
                        }
                    }
                    if ((hits == 1) && (letterList.Contains(letter)))
                    {
                        log("Method:Thinking (leaving unique letter selection(letter was found))", 642);
                        return letter;
                    }
                }
            }
            log("Method:Thinking (leaving unique letter selection(letter was not found))", 647);
            return '*'; 
        }

        /// <summary>
        /// Guesses the vowels to help shorten the list of possibles down. 35 is passed to say a click must be sent from this method.
        /// </summary>
        /// <param name="currentLength"></param>
        /// <returns></returns>
        public char SmartChoice(int currentLength)
        {//later can use length to break it down even more
            //if 35 is recieved as a length it needs to send a click
            log("Method:SmartChoice (Entering SmartChoice)", 659);
            bool keepGoing = true;
            while (keepGoing)
            {
                switch (rnd.Next(0, 5))
                {
                    case 0:
                        //a
                        if (letterList.Contains('A'))
                        {
                            log("Method:SmartChoice (Picking 'A')", 669);
                            choice = 'A';
                            keepGoing = false;
                            if (currentLength == 35)
                            {
                                log("Method:SmartChoice (Picking 'A'and sending click)", 674);
                                //time.Enabled = false;
                                CurrentlyBusy = false;
                                letterList.Remove('A');//takes the picked letter out of the list
                                SendClick(clickPoints["Letter A"]);
                                log("Method:SmartChoice (Picking 'A' and the click was sent)", 679);
                            }
                            log("Method:SmartChoice (Leaving Picking 'A')", 681);
                        }
                        break;
                    case 1:
                        //e
                        if (letterList.Contains('E'))
                        {
                            log("Method:SmartChoice (Picking 'E')", 688);
                            choice = 'E';
                            keepGoing = false;
                            if (currentLength == 35)
                            {
                                log("Method:SmartChoice (Picking 'E'and sending click)", 693);
                                //time.Enabled = false;
                                CurrentlyBusy = false;
                                letterList.Remove('E');//takes the picked letter out of the list
                                SendClick(clickPoints["Letter E"]);
                                log("Method:SmartChoice (Picking 'E' and the click was sent)", 698);
                            }
                            log("Method:SmartChoice (Leaving Picking 'E')", 700);
                        }
                        break;
                    case 2:
                        //i
                        if (letterList.Contains('I'))
                        {
                            log("Method:SmartChoice (Picking 'I')", 707);
                            choice = 'I';
                            keepGoing = false;
                            if (currentLength == 35)
                            {
                                log("Method:SmartChoice (Picking 'I'and sending click)", 712);
                                //time.Enabled = false;
                                CurrentlyBusy = false;
                                letterList.Remove('I');//takes the picked letter out of the list
                                SendClick(clickPoints["Letter I"]);
                                log("Method:SmartChoice (Picking 'E' and the click was sent)", 717);
                            }
                            log("Method:SmartChoice (Leaving Picking 'E')", 719);
                        }
                        break;
                    case 3:
                        //o
                        if (letterList.Contains('O'))
                        {
                            log("Method:SmartChoice (Picking 'O')", 726);
                            choice = 'O';
                            keepGoing = false;
                            if (currentLength == 35)
                            {
                                log("Method:SmartChoice (Picking 'O'and sending click)", 731);
                                //time.Enabled = false;
                                CurrentlyBusy = false;
                                letterList.Remove('O');//takes the picked letter out of the list
                                SendClick(clickPoints["Letter O"]);
                                log("Method:SmartChoice (Picking 'O' and the click was sent)", 736);
                            }
                            log("Method:SmartChoice (Leaving Picking 'O')", 738);
                        }
                        break;
                    case 4:
                        //u
                        if (letterList.Contains('U'))
                        {
                            log("Method:SmartChoice (Picking 'U')", 745);
                            choice = 'U';
                            keepGoing = false;
                            if (currentLength == 35)
                            {
                                log("Method:SmartChoice (Picking 'U'and sending click)", 750);
                                //time.Enabled = false;
                                CurrentlyBusy = false;
                                letterList.Remove('U');//takes the picked letter out of the list
                                SendClick(clickPoints["Letter U"]);
                                log("Method:SmartChoice (Picking 'U' and the click was sent)", 755);
                            }
                            log("Method:SmartChoice (Leaving Picking 'U')", 757);
                        }
                        break;
                }
                if ((!letterList.Contains('U')) && (!letterList.Contains('A')) && (!letterList.Contains('E')) && (!letterList.Contains('I')) && (!letterList.Contains('O')))
                {
                    /*word had no vowels in it
                     * only word that ive encountered with that is fly
                     * sidenote- wrote a side project just to check and the only word it returned with no vowels was fly
                     */
                    log("Method:SmartChoice (Picking 'F')", 767);
                    choice = 'F';
                    keepGoing = false;
                    if (currentLength == 35)
                    {
                        log("Method:SmartChoice (Picking 'F'and sending click)", 772);
                        //time.Enabled = false;
                        CurrentlyBusy = false;
                        letterList.Remove('F');//takes the picked letter out of the list
                        SendClick(clickPoints["Letter F"]);
                        log("Method:SmartChoice (Picking 'F' and the click was sent)", 777);
                    }
                    log("Method:SmartChoice (Leaving Picking 'F')", 779);
                }
                else if ((!letterList.Contains('U')) && (!letterList.Contains('A')) && (!letterList.Contains('E')) && (!letterList.Contains('I')) && (!letterList.Contains('O') && (!letterList.Contains('F'))))
                {
                    log("Method:SmartChoice (Pick random)", 783);
                    choice = '*';//pick randomly
                    keepGoing = false;
                    log("Method:SmartChoice (Leaving Pick random)", 786);
                }

            }
            log("Method:SmartChoice (Leaving SmartChoice)", 790);
            return choice;
        }

        #region Old Get Secret Numnber
        // Preserving this because it is a useful reference for another way to do things.
        //private void GetSecretNumber()
        //{
        //    HttpWebResponse response = null;
        //    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.pisymbol.com/games/hangm/hangm.php?i=0&s=739");
        //    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        //    //CookieContainer cookies = new CookieContainer();
        //    request.KeepAlive = true;
        //    request.AllowAutoRedirect = true;
        //    request.Headers.Set(HttpRequestHeader.CacheControl, "max-age=0");
        //    request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.162 Safari/535.19";
        //    request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        //    request.Referer = " c";
        //    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        //    request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.8");
        //    request.Headers.Set(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
        //    response = (HttpWebResponse)request.GetResponse();

        //    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        //    {
        //        string output = sr.ReadToEnd();
        //        Regex regSID = new Regex(@"[A-Z]+[ ]");
        //        //ONLY FOR PULLING OUT THE LETTERS USED!!!!
        //        regSID.Replace("!!DOCTYPE", " ").Replace("HTML", " ").Replace("DTD", " ").Replace("BODY", " ");
        //        string ReplacedMatch = regSID.ToString();
        //        MatchCollection matches = regSID.Matches(output);
        //        foreach (Match m in matches)
        //        {
        //            GroupCollection groups = m.Groups;
        //            lbWordCollection.Items.Add(groups[1].Value);
        //        }
        //    }
        //}//Method not needed!!!
        #endregion

        private void btnStart_Click(object sender, EventArgs e)
        {
            log("Method:btnStart_Click (Game cycle is started)", 832);
            FiddlerApplication.BeforeResponse += FiddlerApplication_BeforeResponse;
            FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;
            FiddlerApplication.Startup(8877, oFCSF);
            FiddlerApplication.Log.LogString("Starting with settings: [" + oFCSF + "]");
            oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, sSecureEndpointHostname);
            if (null != oSecureEndpoint)
            {
                FiddlerApplication.Log.LogString("Created secure end point listening on port " + iSecureEndpointPort + ", using a HTTPS certificate for '" + sSecureEndpointHostname + "'");
            }
            lblIsRunning.Text = "Program Running.";
            lbWordCollection.DataSource = null;
            btnStop.Enabled = true;
            btnStart.Enabled = false;
            lblStopped.Visible = false;
            lblRunning.Visible = true;
            firstTry = true;
            letterList.Clear();
            letterList.AddRange(alphabet);
            log("Method:btnStart_Click (Asking if game was stopped because of limit)", 851);
            Form2 limitAsk = new Form2();
            if (MessageBox.Show("Are you starting after the game limit has been reached?", "Game Start Options", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                limitAsk.ShowDialog();
                gameLimit = limitAsk.gamesToPlay;
                //Game Limit was reached, so start another new game
                SendClick(clickPoints["New Game Button(After Win or Loss)"]);
                time.Enabled = true;
                log("Method:btnStart_Click (game was stopped beacuse of limit)", 860);
            }
            else
            {
                limitAsk.ShowDialog();
                gameLimit = limitAsk.gamesToPlay;
                log("Method:btnStart_Click (game wasn't stopped beacuse of limit)", 866);
                SmartChoice(35);//35 denotes being called from a different place, Meaning smartchoice shouldn't return a choice,it should click
            }
            time.Elapsed += new ElapsedEventHandler(time_Elapsed);
            time.Enabled = false;
            log("Method:btnStart_Click (Leaving btnStart_Click)", 871);
        }

        void FiddlerApplication_BeforeResponse(Session oSession)
        {
            var foo = oSession.GetResponseBodyAsString();
            ProcessResponse(foo);
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            log("Method:btnStart_Click (Entering btnStop_Click)", 882);
            FiddlerApplication.BeforeResponse -= FiddlerApplication_BeforeResponse;
            FiddlerApplication.oProxy.Detach();
            Thread.Sleep(100);
            FiddlerApplication.Shutdown();
            btnStop.Enabled = false;
            btnStart.Enabled = true;
            lblIsRunning.Text = "Program Stopped";
            lblStopped.Visible = true;
            lblRunning.Visible = false;
            log("Method:btnStart_Click (Leaving btnStop_Click)", 892);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            log("Method:Form1_FormClosing (Entering Form1_FormClosing)", 897);
            FiddlerApplication.BeforeResponse -= FiddlerApplication_BeforeResponse;
            FiddlerApplication.oProxy.Detach();
            Thread.Sleep(100);
            FiddlerApplication.Shutdown();
            log("Method:Form1_FormClosing (Leaving Form1_FormClosing)", 902);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            log("Method:Form1_Load (Entering Form1_Load)", 907);
            AddToDictionary();
            btnStop.Enabled = false;
            lblStopped.Visible = true;
            wordsPrevUsed();
            log("Method:Form1_Load (Leaving Form1_Load)", 912);
        }

        /// <summary>
        /// Gets the words previously used from a file and the game stats.
        /// </summary>
        public void wordsPrevUsed()
        {
            log("Method:wordsPrevUsed (Entering wordsPrevUsed)", 920);
            vowelList.Add('a');
            vowelList.Add('e');
            vowelList.Add('i');
            vowelList.Add('o');
            vowelList.Add('u');
            //Pull the words in from file
            log("Method:wordsPrevUsed (Entering pulling in the previous game words)", 927);
            using (StreamReader sr = new StreamReader("C:\\Users\\tgabelhart\\Documents\\WordList.txt"))
            {
                while (!sr.EndOfStream)
                {
                    String line = sr.ReadLine();
                    if (!line.Contains("Games Played"))
                    {
                        prevGameWordList.Add(line);
                    }
                    else//gather all the games played and win loss data
                    {
                        line = line.Replace("Games Played", "*").Replace("Games Won", "*").Replace("Games Lost", "*").Replace(":","");
                        string[] Gamedata = line.Split('*');
                        //[0] is an empty string
                        //[1] is total games played
                        //[2] is games won
                        //[3] is games lost
                        if (firstTry)
                        {
                            int Val1, Val2, Val3 = 0;
                            int.TryParse(Gamedata[1], out Val1);
                            totalGamesPlayed += Val1;
                            int.TryParse(Gamedata[2], out Val2);
                            TotalWin += Val2;
                            int.TryParse(Gamedata[3], out Val3);
                            TotalLoss += Val3;
                        }
                    }
                }
                //changed base value of totalGamesPlayed for testing(From 0 to 1)
                //TAKE THIS OUT!!!!! RE SETTING VALUE AFTER ITS BEEN FOUND 929
                //ADD in a check that if gamesplayed %10 = 0 then write current list to file
                //also add in the ask for how many games should be played
                decimal percentWin = 0M;
                if (totalGamesPlayed > 0)
                {
                    percentWin = ((decimal)TotalWin / (decimal)totalGamesPlayed) * 100;
                }
                lblTotalGamesPlayed.Invoke((Action)(() => { lblTotalGamesPlayed.Text = "Total # of Games Played: " + totalGamesPlayed + "\nTotal Games Won: " + TotalWin + "\nTotal Games Lost: " + TotalLoss + "\nPercent of Games Won: " + percentWin.ToString("F") + "%"; }));
                TotalWin = 0;
                TotalLoss = 0;
                log("Method:wordsPrevUsed (Leaving pulling in the previous game words)", 969);
            }
            prevGameWordList.Sort();
            wordDict.Clear();
            if (firstTry)
            {
                log("Method:wordsPrevUsed (Entering counting how many times a word has been found)", 975);
                foreach (var item in prevGameWordList)
                {
                    if (wordDict.ContainsKey(item))
                    {
                        wordDict[item]++;
                    }
                    else
                    {
                        wordDict.Add(item, 1);
                    }
                }
                lbPrevWords.Invoke((Action)(() => { lbPrevWords.Items.Clear(); }));
                foreach (var item in wordDict)
                {
                    lbPrevWords.Invoke((Action)(() => { lbPrevWords.Items.Add(item.Key + " Appeared # of Times: " + item.Value); }));
                }
                foreach (var item in prevGameWordList)
                {
                    char[] itemArray = item.ToCharArray();
                    foreach (var letter in itemArray)
                    {
                        if (letterDict.ContainsKey(letter))
                        {
                            letterDict[letter]++;
                        }
                        else
                        {
                            letterDict.Add(letter, 1);
                        }
                    }
                }
                if (gamesPlayed > 100)
                {
                    log("Method:wordsPrevUsed (Entering Random letter list population)", 1009);
                    foreach (var item in letterDict)
                    {
                        if ((item.Value > 250) && !vowelList.Contains(item.Key) && !RandomList.Contains(item.Key))
                        {
                            RandomList.Add(Char.ToUpper(item.Key));
                        }
                    }
                    log("Method:wordsPrevUsed (Leaving Random letter list population)", 1017);
                }
                log("Method:wordsPrevUsed (Leaving counting how many times a word has been found)", 1019);
            }
            firstTry = false;
            #region anotherWayToDoIt
            /*
            PrevGameWordList.Sort();
            int listcount = PrevGameWordList.Count();
            int counter = 0;
            int occurance = 0;
            while (counter < listcount)
            {
                String currentWord = PrevGameWordList.ElementAt(counter);
                int next = counter + 1;
                String nextWord = PrevGameWordList.ElementAt(next);
                if (currentWord.Equals(nextWord))
                {
                    occurance++;
                }
                else
                {
                    lbPrevWords.Items.Add(currentWord + " # of times appeared: " + occurance);
                    occurance = 0;
                }
                counter++;

            }*/
            #endregion
            log("Method:wordsPrevUsed (Leaving wordsPrevUsed)", 1005);
        }

        /// <summary>
        /// Writes where the program last was and the line number of it to a log file.
        /// </summary>
        /// <param name="whereAmI"></param>
        /// <param name="lineNum"></param>
        public void log(String whereAmI,int lineNum)
        {
            //Thread.Sleep(100);see if this changes the speed of the program at all
            using (StreamWriter w = File.AppendText("C:\\Users\\tgabelhart\\Documents\\Log.txt"))
            {
                w.WriteLine("Program is at " + whereAmI + " at line number: " + lineNum + " During game #: " + gamesPlayed);
            }
        }

        public void time_Elapsed(object sender, ElapsedEventArgs e)
        {
            //Send a click because the game was over
            log("Method:time_Elapsed (Entering time_Elapsed)", 1066);
            SmartChoice(35);
            time.Enabled = false;
            log("Method:time_Elapsed (Leaving time_Elapsed)", 1068);
        }

        //public void FirstClick()//Can Be Taken out Soon
        //{
        //    time.Enabled = false;
        //    CurrentlyBusy = false;
        //    index = rnd.Next(0, letterList.Count); // Pick one at random
        //    letter = letterList[index];
        //    letterList.RemoveAt(index);//takes the picked letter out of the list
        //    switch (letter)
        //    {
        //        case 'A':
        //            SendClick(clickPoints["Letter A"]);
        //            break;
        //        case 'B':
        //            SendClick(clickPoints["Letter B"]);
        //            break;
        //        case 'C':
        //            SendClick(clickPoints["Letter C"]);
        //            break;
        //        case 'D':
        //            SendClick(clickPoints["Letter D"]);
        //            break;
        //        case 'E':
        //            SendClick(clickPoints["Letter E"]);
        //            break;
        //        case 'F':
        //            SendClick(clickPoints["Letter F"]);
        //            break;
        //        case 'G':
        //            SendClick(clickPoints["Letter G"]);
        //            break;
        //        case 'H':
        //            SendClick(clickPoints["Letter H"]);
        //            break;
        //        case 'I':
        //            SendClick(clickPoints["Letter I"]);
        //            break;
        //        case 'J':
        //            SendClick(clickPoints["Letter J"]);
        //            break;
        //        case 'K':
        //            SendClick(clickPoints["Letter K"]);
        //            break;
        //        case 'L':
        //            SendClick(clickPoints["Letter L"]);
        //            break;
        //        case 'M':
        //            SendClick(clickPoints["Letter M"]);
        //            break;
        //        case 'N':
        //            SendClick(clickPoints["Letter N"]);
        //            break;
        //        case 'O':
        //            SendClick(clickPoints["Letter O"]);
        //            break;
        //        case 'P':
        //            SendClick(clickPoints["Letter P"]);
        //            break;
        //        case 'Q':
        //            SendClick(clickPoints["Letter Q"]);
        //            break;
        //        case 'R':
        //            SendClick(clickPoints["Letter R"]);
        //            break;
        //        case 'S':
        //            SendClick(clickPoints["Letter S"]);
        //            break;
        //        case 'T':
        //            SendClick(clickPoints["Letter T"]);
        //            break;
        //        case 'U':
        //            SendClick(clickPoints["Letter U"]);
        //            break;
        //        case 'V':
        //            SendClick(clickPoints["Letter V"]);
        //            break;
        //        case 'W':
        //            SendClick(clickPoints["Letter W"]);
        //            break;
        //        case 'X':
        //            SendClick(clickPoints["Letter X"]);
        //            break;
        //        case 'Y':
        //            SendClick(clickPoints["Letter Y"]);
        //            break;
        //        case 'Z':
        //            SendClick(clickPoints["Letter Z"]);
        //            break;
        //    }
        //}
    }
}